package com.iflytek.uoamp.agent.monitor.lib;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.log4j.Logger;

import com.iflytek.uoamp.agent.core.sender.monitorsender.requestObj.MonitorItemConfig;
import com.iflytek.uoamp.agent.core.sender.monitorsender.requestObj.MonitorItemResult;
import com.iflytek.uoamp.agent.monitor.mcagent.MCAgentConfig;


public class ParseLibResult{

	private static Lock lock = new ReentrantLock();
	@SuppressWarnings("rawtypes")
	private Map<String,Comparable> warningMap = new HashMap<String,Comparable>();
	@SuppressWarnings("rawtypes")
	private Map<String,Comparable> criticalMap = new HashMap<String,Comparable>();
	private Map<String,String> timeCatch = new HashMap<String,String>();
	private static Set<String> checkNames = new HashSet<String>();
	

	@SuppressWarnings("rawtypes")
	private Comparable convertObj(String cur){
		return Double.parseDouble(cur);
	}
	
	/**
	 * unpack byte[] value,this value is per value
	 * */
	private String[] unpack(byte[] contentByte){
		String content;
		try {
			content = new String(contentByte,"utf-8");
		} catch (UnsupportedEncodingException e) {
			Logger.getRootLogger().error(e.getMessage(),e);
			content = new String(contentByte);
		}
		String[] keys = content.split((char)31+"");
		return keys;
	}
	
	
	public static String setToString() {
		lock.lock();
		try{
			if (checkNames == null){
				return "";
			}
			StringBuilder temp = new StringBuilder();
			for (String cur : checkNames) {
				temp.append(cur + ",");
			}
			return temp.toString();
		}finally{
			lock.unlock();
		}
	}
	
	/**
	 * 初始化；
	 * @param itemsConfig
	 */
	public void init(List<MonitorItemConfig> itemsConfig){
		lock.lock();
		try{
			if(itemsConfig==null){
				return;
			}
			
			for(MonitorItemConfig cur:itemsConfig){
				
				timeCatch.put(cur.getServerDesc(), cur.getUptime());
				
				checkNames.remove(cur.getServerDesc());
				if (cur.getServerUrl()!=null) {
					checkNames.add(cur.getServerDesc());
				}
				String wvalue = cur.getWaringLimit();
				if(wvalue==null){
					continue;
				}
				
				String key = cur.getServerDesc() +"|"+ cur.getHost();
				
				String[] wvs = wvalue.split(",");
				for(String cw:wvs){
					String[] values = cw.split("=");
					if(values==null || values.length<2){
						continue;
					}
					warningMap.remove(key+"|"+values[0]);
					if (cur.getServerUrl()!=null) {
						warningMap.put(key+"|"+values[0], convertObj(values[1]));
					}
				}
	
				String[] cvs = wvalue.split(",");
				for(String cc:cvs){
					String[] values = cc.split("=");
					if(values.length==2){
						criticalMap.remove(key+"|"+values[0]);
						if (cur.getServerUrl()!=null) {
							criticalMap.put(key+"|"+values[0], convertObj(values[1]));
						}
					}
					
				}
				
			}
			
		}finally{
			lock.unlock();
		}
	}
	
	/**
	 * 将flied转化为对象
	 * @param host
	 * @param desc
	 * @param errorLevel
	 * @param result
	 * @return
	 */
	private MonitorItemResult getResult(String host,String desc,Integer errorLevel,String result){
		MonitorItemResult monitorResult = new MonitorItemResult();
		monitorResult.setComponentType("checklib");
		monitorResult.setHeader(new HashMap<String, String>());
		monitorResult.setHost(host);
		monitorResult.setOutput(result);
		monitorResult.setReturnCode(errorLevel+"");
		monitorResult.setServerDesc(desc);
		monitorResult.setUptime(timeCatch.get(desc));
		monitorResult.setSendhost(MCAgentConfig.getInstance().getMonitoredPointIp());
		return monitorResult;
	}
	
	/**
	 * 将获取状态码和字符串
	 * @param warningOutput
	 * @param criticalOutput
	 * @param perResult
	 * @return
	 */
	private Object[] getMonitorItemResult(StringBuilder warningOutput,StringBuilder criticalOutput,StringBuilder perResult){
		int errorLevel = 0;
		String result = "";
		
		if(!criticalOutput.toString().isEmpty()){
			errorLevel = 2; 
			result = ("状态异常"+criticalOutput.toString()+","+warningOutput.toString()+"|"+perResult.toString());
		}else if(!warningOutput.toString().isEmpty()){
			errorLevel = 1; 
			result = ("状态告警"+warningOutput.toString()+"|"+perResult.toString());
		}else{
			errorLevel = 0;
			result = ("状态正常|"+perResult.toString());
		}

		return new Object[]{errorLevel,result};
	}
	
	/**
	 * 判断 lib 传来的数据是否需要告警
	 * @param host
	 * @param desc
	 * @param content
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public MonitorItemResult getErrorLevel(String host,String desc,byte[] content){
		String[] values = unpack(content);
		StringBuilder perResult = new StringBuilder();
		StringBuilder warningOutput = new StringBuilder();
		StringBuilder criticalOutput = new StringBuilder();
		String result = null;
		try{
			for(String cur:values){
				String[] cv = cur.split(":");
				
				String key = desc +"|"+host+"|"+cv[0];
				Comparable warningLimit = null;
				Comparable critcalLimit = null;
				lock.lock();
				try{
					warningLimit = warningMap.get(key);
					critcalLimit = criticalMap.get(key);
				}finally{
					lock.unlock();
				}
				Comparable curvalue= convertObj(cv[1]);
				
				if(warningLimit==null){
					perResult.append(cv[0]+"="+cv[1]+" ");
					continue;
				}
				if(curvalue instanceof Double){
					if(critcalLimit!=null && curvalue.compareTo((Double)critcalLimit)>0){
						criticalOutput.append(cv[0]+"="+cv[1]+" ");
					}else if(curvalue.compareTo((Double)warningLimit)>0){
						warningOutput.append(cv[0]+"="+cv[1]+" ");
					}
				}else{
					if(critcalLimit!=null && curvalue.compareTo(critcalLimit)>0){
						criticalOutput.append(cv[0]+"="+cv[1]+" ");
					}else if(curvalue.compareTo(warningLimit)>0){
						warningOutput.append(cv[0]+"="+cv[1]+" ");
					}
				}
				
			}
			
			Object[] obj = getMonitorItemResult(warningOutput,criticalOutput,perResult);
			return getResult(host,desc,(Integer)obj[0],(String)obj[1]);
			
		}catch(Exception e){
			Logger.getRootLogger().error(e.getMessage(),e);	
			result = ("状态未知|"+criticalOutput.toString()+","+warningOutput.toString()+"|"+perResult.toString());
		}
		return getResult(host,desc,3,result);
	}
	
	/**
	 * 判断 log 传来的数据是否需要告警
	 * @param host
	 * @param desc
	 * @param content
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public MonitorItemResult getErrorLevel4Long(String host,String desc,String key,Long value){
		StringBuilder perResult = new StringBuilder();
		StringBuilder warningOutput = new StringBuilder();
		StringBuilder criticalOutput = new StringBuilder();
		String result = "";
		try{

			Comparable warningLimit = warningMap.get(key);
			Comparable critcalLimit = criticalMap.get(key);
			
			if(warningLimit==null){
				perResult.append("failnum="+value+" ");
			}else{
				if(critcalLimit!=null && value.compareTo((Long)critcalLimit)>0){
					criticalOutput.append("failnum="+value+" ");
				}else if(value.compareTo((Long)warningLimit)>0){
					warningOutput.append("failnum="+value+" ");
				}
			}

			Object[] obj = getMonitorItemResult(warningOutput,criticalOutput,perResult);
			return getResult(host,desc,(Integer)obj[0],(String)obj[1]);
			
		}catch(Exception e){
			Logger.getRootLogger().error(e.getMessage(),e);	
			result = ("状态未知|"+criticalOutput.toString()+","+warningOutput.toString()+"|"+perResult.toString());
		}
		return getResult(host,desc,3,result);
	}
	
}
